package com.tang.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.result.UpdateResult;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Component("mongoDb")
public class MongoDbService {

    @Resource
    private MongoDatabase mdb;

    /**
     * 插入一个文档
     *
     * @param document   文档
     * @param collection 相关的集合
     */
    public void insert(Document document, String collection) throws Exception {
        mdb.getCollection(collection).insertOne(document);
    }

    /**
     * 批量插入文档
     *
     * @param list       文档列表
     * @param collection 相关的集合
     */
    public void insertList(List<Document> list, String collection)
            throws Exception {
        mdb.getCollection(collection).insertMany(list);
    }

    /**
     * 分页查询所有文档
     *
     * @param collection 相关的集合
     * @param page       当前页
     * @param pageSize   每页的大小
     * @return
     */
    public List<Document> findAll(String collection, Integer page,
                                  Integer pageSize) throws Exception {
        List<Document> results = new ArrayList<Document>();
        FindIterable<Document> iterables = null;
        if (null != page && null != pageSize) {
            iterables = mdb.getCollection(collection).find().skip(page)
                    .limit(pageSize);
        } else {
            iterables = mdb.getCollection(collection).find();
        }
        MongoCursor<Document> cursor = iterables.iterator();
        while (cursor.hasNext()) {
            Document doc = cursor.next();
            String _id = doc.getObjectId("_id").toString();
            doc.append("_id", _id);
            results.add(doc);
        }
        return results;
    }

    /**
     * 根据条件查询
     *
     * @param filter     过滤条件
     * @param collection 相关的集合
     * @param page       当前页
     * @param pageSize   每页的大小
     * @return
     */
    public List<Document> findBy(Bson filter, String collection, Integer page,
                                 Integer pageSize) throws Exception {
        List<Document> results = new ArrayList<Document>();
        FindIterable<Document> iterables = null;
        if (null != page && null != pageSize) {
            iterables = mdb.getCollection(collection).find(filter).skip(page)
                    .limit(pageSize);
        } else {
            iterables = mdb.getCollection(collection).find(filter);
        }
        MongoCursor<Document> cursor = iterables.iterator();
        while (cursor.hasNext()) {
            Document doc = cursor.next(); //创建一个新的Document,并将mongoCursor中的document赋上
            ObjectId objectId = doc.getObjectId("_id"); //获取文档当中的ObjectId
            doc.put("_id", objectId.toString());
            results.add(doc);
        }
        return results;
    }

    /**
     * 更新查询到的第一个
     *
     * @param map
     * @param collection
     * @throws Exception
     */
    public void updateOne(Map<String, Object> map, String collection)
            throws Exception {
        mdb.getCollection(collection).updateOne((Document) map.get("filter"),
                (Document) map.get("update"));
    }

    /**
     * 批量更新相关的文档
     *
     * @param model      封装成json格式的查询参数，批量更新时必须每一项包含_id
     * @param collection 相关的集合
     * @throws Exception
     */
    public void updateMany(String model, String collection) throws Exception {
        JSONArray json = JSONObject.parseArray(model);
        int size = json.size();
        for(int i = 0; i < size; i++) {
            JSONObject job = json.getJSONObject(i);
            Set<String> keys = job.keySet();
            Document doc = new Document();
            Document filter = new Document();
            for(String key : keys) {
                if ("_id".equals(key)) {
                    filter.append("_id", new ObjectId(job.getString("_id")));
                } else {
                    doc.append(key, job.getString(key));
                }
            }
            Document update = new Document();
            update.append("$set", doc);
            mdb.getCollection(collection).updateMany(filter, update);
        }
    }

    /**
     * 更新一个文档, 结果是replacement是新文档，老文档完全被替换
     *
     * @param filter      查询条件
     * @param replacement 跟新文档
     * @param collection  相关的集合
     */
    public UpdateResult replaceOne(Bson filter, Document replacement,
                                   String collection) throws Exception {
        UpdateResult result = mdb.getCollection(collection).replaceOne(filter,
                replacement);
        return result;
    }

    /**
     * 根据条件删除一个文档
     *
     * @param filter     查询条件
     * @param collection 相关的集合
     */
    public void deleteOne(Bson filter, String collection) throws Exception {
        mdb.getCollection(collection).deleteOne(filter);
    }

    /**
     * 根据条件删除多个文档
     *
     * @param model
     * @param collection 相关的集合
     * @throws Exception
     */
    public void deleteMany(String model, String collection) throws Exception {
        JSONArray json = JSONObject.parseArray(model);
        int size = json.size();
        for(int i = 0; i < size; i++) {
            JSONObject job = json.getJSONObject(i);
            Set<String> keys = job.keySet();
            Document filter = new Document();
            for(String key : keys) {
                filter.append(key, new ObjectId(job.getString(key)));
            }
            mdb.getCollection(collection).deleteMany(filter);
        }
    }

    /**
     * 删除相关的的集合
     *
     * @param collection 相关的集合
     */
    public void deleteConllection(String collection) throws Exception {
        mdb.getCollection(collection).drop();
    }

    // public static void main(String[] args) {
    // Document filter = new Document();
    // filter.append("userName", "詹姆斯");
    // List<Document> results = new ArrayList<Document>();
    // MongoClient client = new MongoClient("115.159.201.120", 27017);
    // MongoDatabase mdb = client.getDatabase("saas_report");
    // FindIterable<Document> iterables = mdb.getCollection("student").find(
    // filter).skip(1)
    // .limit(2);
    // MongoCursor<Document> cursor = iterables.iterator();
    // while (cursor.hasNext()) {
    // results.add(cursor.next());
    // }
    // System.out.println("获得的列表是"+results);
    // }

    // public static void main(String[] args) {
    // String _id = "{" + "\"" + "timestamp" + "\"" + ": 1527038009" + ","
    // + "\"" + "machineIdentifier" + "\"" + ": 868807" + "," + "\""
    // + "processIdentifier" + "\"" + ": 24153" + "," + "\""
    // + "counter" + "\"" + ": 8426512" + "," + "\"" + "date" + "\""
    // + ": 1527038009000" + "," + "\"" + "time" + "\""
    // + ": 1527038009000" + "," + "\"" + "timeSecond" + "\""
    // + ": 1527038009" + "}";
    // ObjectId ob = new ObjectId(_id);
    // System.out.println(ob);
    // }
}
